/**
 * 
 */
package vue;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.Semaphore;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import controleur.Fleche;
import controleur.InitialisationJeu;
import controleur.Moins;
import controleur.PauseJeu;
import controleur.Plus;
import controleur.VideJeu;

import model.Cellule;
import model.Coordonnee;
import model.Environnement;
import model.ThreadEnvironnement;

/**
 * @author Florian.B Rachid.D
 * 
 */
public class PanneauPrincipal extends JPanel implements Observer {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private JPanel pg = null;
	private VCellule[][] btn = null;
	private int hauteurEnv = 0;
	private int largeurEnv = 0;
	private int dhauteurThis = 0;
	private int dlargeurThis = 0;
	private int fLargeurThis = 0;
	private int fhauteurThis = 0;
	private Semaphore sem = new Semaphore(1);

	public PanneauPrincipal(Environnement env, ThreadEnvironnement t) {
		super(new BorderLayout(1, 1));
		GridLayout g = new GridLayout(env.getHauteur(), env.getLargeur(), 1, 1);
		this.hauteurEnv = env.getHauteur();
		this.largeurEnv = env.getLargeur();
		this.fhauteurThis = env.getHauteur();
		this.fLargeurThis = env.getLargeur();
		pg = new JPanel(g);
		pg.setToolTipText("Plateau du jeu de vie");

		btn = new VCellule[env.getHauteur()][env.getLargeur()];
		for (int i = 0; i < env.getHauteur(); i++)
			for (int j = 0; j < env.getLargeur(); j++) {
				btn[i][j] = new VCellule(new Coordonnee(i, j, env.getHauteur(),
						env.getLargeur()), env, pg, this);

				pg.add(btn[i][j]);
			}
		this.add(pg, BorderLayout.CENTER);
		JPanel pb = new JPanel(new FlowLayout());
		JButton jI = new JButton(new InitialisationJeu(env));
		pb.add(jI);
		JButton jP = new JButton(new PauseJeu(t));
		pb.add(jP);
		JButton jV = new JButton(new VideJeu(env));
		pb.add(jV);
		JButton jPlus = new JButton(new Plus(this, env));
		pb.add(jPlus);
		JButton jMoins = new JButton(new Moins(this, env));
		pb.add(jMoins);
		
		JPanel paneTouch = new JPanel(new GridLayout(2, 3));
		paneTouch.add(new JLabel(""));
		paneTouch.add(new JButton(new Fleche("\u2191", this, env, 2)));
		paneTouch.add(new JLabel(""));
		paneTouch.add(new JButton(new Fleche("\u2190", this, env, 1)));
		paneTouch.add(new JButton(new Fleche("\u2193", this, env, 4)));
		paneTouch.add(new JButton(new Fleche("\u2192", this, env, 3)));
		
		pb.add(paneTouch);
		JButton jTemplate = new TemplateButton();
		pb.add(jTemplate);
		this.add(pb, BorderLayout.SOUTH);
		env.addObserver(this);
	}

	public void reInit(int hauteur, int largeur, Environnement env) {

		if (sem.tryAcquire()) {
			this.remove(pg);
			this.validate();

			GridLayout g = new GridLayout(hauteur, largeur, 1, 1);
			pg = new JPanel(g);
			btn = new VCellule[hauteur][largeur];
			for (int i = 0; i < hauteur; i++)
				for (int j = 0; j < largeur; j++) {
					btn[i][j] = new VCellule(new Coordonnee(i, j, hauteur,
							largeur), env, pg, this);
					pg.add(btn[i][j]);
				}
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {

					add(pg, BorderLayout.CENTER);
				}

			});
			this.revalidate();
			this.hauteurEnv = hauteur;
			this.largeurEnv = largeur;
			this.fhauteurThis = hauteur;
			this.fLargeurThis = largeur;
			this.dlargeurThis = 0;
			this.dhauteurThis = 0;
			sem.release();
		}
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		if (arg0.getClass() != Environnement.class)
			return;
		Environnement env = (Environnement) arg0;
		if (sem.tryAcquire()) {
			if (env.getHauteur() != this.hauteurEnv
					|| env.getLargeur() != this.largeurEnv)
				reInit(env.getHauteur(), env.getLargeur(), env);
			for (int hauteur = dhauteurThis; hauteur < fhauteurThis; hauteur++) {
				for (int largeur = dlargeurThis; largeur < fLargeurThis; largeur++) {
					Cellule cel = env.getCellule(new Coordonnee(hauteur,
							largeur, env.getHauteur(), env.getLargeur()));
					if (cel == null) {
						btn[hauteur][largeur]
								.mort();
					} else {
						btn[hauteur][largeur]
								.vie(cel.getLife());
					}
				}
			}

			sem.release();
		}

	}

	public void plus(Environnement env) {
		if (dlargeurThis < fLargeurThis - 2) {
			dlargeurThis++;
			fLargeurThis--;
		}
		if (dhauteurThis < fhauteurThis - 2) {
			dhauteurThis++;
			fhauteurThis--;
		}
		gestionZoom(env);
	}

	private void gestionZoom(Environnement env) {
		if (sem.tryAcquire()) {

			this.remove(pg);
			this.validate();
			GridLayout g = new GridLayout(fhauteurThis - dhauteurThis,
					fLargeurThis - dlargeurThis, 1, 1);
			pg = new JPanel(g);
			for (int hauteur = dhauteurThis; hauteur < fhauteurThis; hauteur++) {
				for (int largeur = dlargeurThis; largeur < fLargeurThis; largeur++) {
					pg.add(btn[hauteur][largeur]);
				}
			}
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					add(pg, BorderLayout.CENTER);
					
				}

			});
			this.revalidate();
			sem.release();
		}
	}

	public void moins(Environnement env) {
		if (dlargeurThis > 0) {
			dlargeurThis--;
		}
		if (fLargeurThis < largeurEnv)
			fLargeurThis++;
		if (dhauteurThis > 0) {
			dhauteurThis--;
		}
		if (fhauteurThis < hauteurEnv) {
			fhauteurThis++;
		}
		gestionZoom(env);
	}

	public void goUp(Environnement env) {
			if (dhauteurThis > 0) {
				dhauteurThis--;
				fhauteurThis--;
			}
		gestionZoom(env);
	}

	public void goDown(Environnement env) {
		if (fhauteurThis < hauteurEnv) {
			dhauteurThis++;
			fhauteurThis++;
		}
		gestionZoom(env);
	}

	public void goRigth(Environnement env) {
		if (fLargeurThis < largeurEnv) {
			fLargeurThis++;
			dlargeurThis++;
		}
		gestionZoom(env);
	}

	public void goLeft(Environnement env) {
		if (dlargeurThis > 0) {
			fLargeurThis--;
			dlargeurThis--;
		}
		gestionZoom(env);
	}

	public VCellule getVCelluleAt(int hauteur, int largeur) {
		return btn[hauteur][largeur];
	}
}
